﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Picdownload
{
    class DownLoadThread : MyThread
    {
        // ParseResource类用于下载和分析网络资源
        private ParseResource pr = new ParseResource();
        private int currentCount = 0; // 当前下载目录中的网页数
        // 用于向每个线程目录中的index.txt中写当前目录的URL
        private FileIO fileIO = new FileIO();
        private string path; // 当前的下载目录（后面带“\"）
        private string[] patterns; // 线程不下载符合patterns中的正则表达式的URL
        public bool stop = false; // stop为true，线程退出
        public int threadID; // 当前线程的threadID，用于区分其他的线程

        public DownLoadThread(string[] patterns)
        {
            pr.findUrl += findUrl; // 为findUrl事件赋一个方法
            this.patterns = patterns;
        }
        // 这是一个事件方法，每获得一个URL时发生
        private void findUrl(string url)
        {
            Common.addUrl(url); // 将获得的URL加到下载队列中
        }
        private void openFile() // 打开下载目录中的index.txt文件
        {
            fileIO.CloseWriteFile();
            fileIO.OpenWriteFile(path + Common.indexFile);
        }
        public override void run() // 线程运行方法
        {
            LinkedList<string> urls = new LinkedList<string>();
            path = Common.getDir(); // 获得下载目录
            openFile();
            while (!stop)
            {
                // 当下载队列中没有URL时，进行循环等待
                while (!stop && urls.Count == 0)
                {
                    Common.getUrls(urls, 20); // 从下载队列中获得20个url
                    if (urls.Count == 0) // 如果未获得url
                    {
                        // 通知系统当前线程已处于等待状态，
                        // 如果所有的线程都处于等待状态，
                        // 说明所有的网络资源都被下载完了
                        Common.threadWait(threadID);
                        sleep(5000); // 当前线程休眠5秒
                    }
                }
                StringBuilder sb = new StringBuilder();
                foreach (string url in urls) // 循环对这20个url进行循环下载分析
                {
                    if (stop) break;
                    // 如果当前下载目录的资源文件数大于等于最大文件数目时，
                    // 建立一个新目录，并继续下载
                    if (currentCount >= Common.maxCount)
                    {
                        path = Common.getDir();
                        openFile();
                        currentCount = 0; // 目录
                    }
                    // 每个下载资源文件名使用5位的顺序号保存（没有扩展名），
                    // 如00001、00002。下面的语句是格式化文件名
                    string s = string.Format("{0:D5}", currentCount + 1);
                    sb.Remove(0, sb.Length);
                    sb.Append(s);
                    sb.Append(":");
                    sb.Append(url);
                    try
                    {
                        // 下载和分析当前的url
                        pr.parse(url, path + s, patterns);
                        Common.Count++;
                        // 将当前的url写入index.txt
                        fileIO.WriteLine(sb.ToString());
                        currentCount++;
                    }
                    catch (Exception e)
                    {

                    }
                }
                urls.Clear();
            }
        }
    }
}
